/**
 * Copyright (C) 2013-2014 the original author or authors.
 */
package com.foreveross.bsl.comment.web;

import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.foreveross.bsl.comments.application.NoticeService;
import com.foreveross.bsl.comments.application.vo.NoticeVo;
import com.foreveross.bsl.common.utils.exception.ApplicationException;
import com.foreveross.bsl.common.utils.exception.RemoteInvokeException;
import com.foreveross.bsl.common.utils.web.QueryFilter;
import com.foreveross.bsl.common.utils.web.QuerySpecs;
import com.foreveross.bsl.common.utils.web.model.PageMustache;
import com.foreveross.bsl.common.utils.web.model.QueryModelHelper;
import com.foreveross.bsl.common.utils.web.model.SelectBoxModel;
import com.foreveross.bsl.common.utils.web.model.SortInfoModel;
import com.foreveross.bsl.mam.app.application.AppMainApplication;
import com.foreveross.bsl.mam.app.application.vo.AppMainVo;
import com.foreveross.bsl.push.application.PushMgmtService;
import com.foreveross.bsl.push.application.vo.PushRequestVo;
import com.foreveross.bsl.push.application.vo.PushVo;
import com.foreveross.bsl.system.application.ApplicationRegisterApplication;
import com.foreveross.bsl.web.BaseController;
import com.google.common.collect.Maps;

/**
 * xxx
 * 
 * @author Wangyi
 * @version v1.0
 * 
 * @date 2013-7-19
 * 
 */
@Controller
@RequestMapping(value = "/notice")
public class NoticeController extends BaseController {

	@Inject
	private NoticeService noticeService;

	@Inject
	private AppMainApplication appService;

	@Inject
	private ApplicationRegisterApplication appRegClient;

	@Inject
	private PushMgmtService pushMgmtService;

	@RequestMapping(value = "")
	public String list(
			@RequestParam(value = "page", defaultValue = "1") int pageNumber,
			@RequestParam(value = "page.size", defaultValue = PAGE_SIZE) int pageSize,
			@RequestParam(value = "appId", required = false) String appId,
			Model model, HttpServletRequest request) {
		String queryUrl = "/notice";
		QueryModelHelper queryHelper = new QueryModelHelper(queryUrl,
				makeQueryFields(), makeSortInfo());
		QuerySpecs querySpecs = queryHelper.populateQueryModel(model, request);
		if (StringUtils.isNotBlank(appId)) {
			querySpecs.addFilter(QueryFilter.eq("appId", appId));
		}
		Page<NoticeVo> noticePage = noticeService.find(pageNumber, pageSize,
				querySpecs);
		model.addAttribute("notices", noticePage);
		model.addAttribute("appId", appId);
		model.addAttribute("page",
				new PageMustache(noticePage, PAGINATION_SIZE));
		return "notice/list";
	}

	@RequestMapping(value = "push-detail/{pushRequestId}")
	public String showPushDetail(
			@RequestParam(value = "page", defaultValue = "1") int pageNumber,
			@RequestParam(value = "page.size", defaultValue = PAGE_SIZE) int pageSize,
			@PathVariable(value = "pushRequestId") String requestId,
			@RequestParam(value = "appId", required = false) String appId,
			Model model, HttpServletRequest request) {

		String queryUrl = "/push/list-pushs/" + requestId;
		QueryModelHelper queryHelper = new QueryModelHelper(queryUrl,
				makePushDetailQueryFields(), makePushDetailSortInfo());
		QuerySpecs querySpecs = queryHelper.populateQueryModel(model, request);

		model.addAttribute("pushRequest", this.getPushRequestVo(requestId));

		Page<PushVo> pushs = pushMgmtService.findPushsByRequest(requestId,
				pageNumber, pageSize, querySpecs);
		model.addAttribute("pushs", pushs);
		model.addAttribute("page", new PageMustache(pushs, PAGINATION_SIZE));
		model.addAttribute("appId", appId);
		model.addAttribute("requestId", requestId);

		return "notice/push-detail";
	}

	private PushRequestVo getPushRequestVo(String requestId) {
		QuerySpecs querySpecs = new QuerySpecs();
		querySpecs.addFilter(QueryFilter.eq("id", requestId));
		Page<PushRequestVo> page = this.pushMgmtService.findPushRequests(1, 1,
				querySpecs);
		if (page.getContent().size() <= 0) {
			throw new ApplicationException("不在存推送请求对象:" + requestId);
		}
		return page.getContent().get(0);
	}

	private final SelectBoxModel makeQueryFields() {
		SelectBoxModel sbm = new SelectBoxModel();
		sbm.addOption("LIKE_title", "标题", true);
		sbm.addOption("LIKE_content", "内容");
		return sbm;
	}

	private final SortInfoModel makeSortInfo() {
		SortInfoModel sim = new SortInfoModel();
		sim.setSortEntry("createTime", "创建时间", false);
		sim.setSortEntry("title", "标题", true);
		return sim;
	}

	private final SelectBoxModel makePushDetailQueryFields() {
		SelectBoxModel sbm = new SelectBoxModel();
		sbm.addOption("LIKE_target.deviceId", "设备ID", true);
		sbm.addOption("EQ_target.alias", "用户名");
		sbm.addOption("EQ_status", "推送状态");
		return sbm;
	}

	private final SortInfoModel makePushDetailSortInfo() {
		SortInfoModel sim = new SortInfoModel();
		sim.setSortEntry("create_time", "创建时间", false);
		sim.setSortEntry("target.alias", "用户名", true);
		return sim;
	}

	@RequestMapping(value = "{noticeId}", method = RequestMethod.GET)
	public @ResponseBody
	NoticeVo fetchNotice(@PathVariable("noticeId") String noticeId) {
		return noticeService.getById(noticeId);
	}

	@RequestMapping(value = "create", method = RequestMethod.GET)
	public String createForm(Model model,
			@RequestParam(value = "appId", required = false) String appId) {
		AppMainVo app = null;
		if (!StringUtils.isEmpty(appId)) {
			app = this.appService.getEntity(appId);
		} else {
			List<AppMainVo> apps = this.appService.findAll();
			if (apps != null && !apps.isEmpty()) {
				app = apps.get(0);
				model.addAttribute("apps", apps);
				model.addAttribute("hasApps", true);
			}
		}
		if (app != null) {
			String appKey = getAppKeyByAppId(app.getId());
			String[] roles = this.doGetRoles(appKey);
			model.addAttribute("appId", appId);
			model.addAttribute("appName", app.getApp_name());
			model.addAttribute("roles", roles);
			model.addAttribute("hasRoles", roles != null && roles.length > 0);
		}
		return "notice/notice-form";
	}

	private String[] doGetRoles(String appKey) {
		String[] roles = this.noticeService.getRoles(appKey);
		return roles;
	}

	@RequestMapping(value = "roles/{appId}", method = RequestMethod.GET)
	@ResponseBody
	public Map<String, Object> getRoles(@PathVariable("appId") String appId) {
		String appKey = getAppKeyByAppId(appId);
		String[] roles = this.doGetRoles(appKey);
		Map<String, Object> result = Maps.newHashMap();
		result.put("result", true);
		result.put("roles", roles);
		return result;
	}

	private String getAppKeyByAppId(String appId) {
		String appKey = appRegClient.getAppKeyByAppId(appId);
		if (appKey == null) {
			throw new IllegalArgumentException("appId:" + appId + "对应的appKey为空");
		}
		return appKey;
	}

	@RequestMapping(value = "create", method = RequestMethod.POST)
	public String create(
			@RequestParam(value = "roleType", defaultValue = "1") String roleType,
			NoticeVo notice, RedirectAttributes redirectAttributes,
			HttpServletRequest request) {
		redirectAttributes.addAttribute("appId", request.getParameter("appId"));
		try {
			if ("0".equals(roleType) && !notice.hasRoles()) {
				throw new ApplicationException("没有指定任何角色");
			}
			notice.setBusiDetail(true);
			this.noticeService.add(notice);
			redirectAttributes.addFlashAttribute("message", "创建公告成功");
			return "redirect:/notice";
		} catch (Exception e) {
			String msg = "操作发生错误：" + e.getMessage();
			;
			if (e instanceof RemoteInvokeException) {
				msg = ((RemoteInvokeException) e).getExceptionSpec()
						.getMessage();
				if (msg.contains("沒有找到任何目标设备")) {
					msg = "提交公告推送错误：该应用或角色下没有任务设备";
				}
			}
			redirectAttributes.addFlashAttribute("notice", notice);
			redirectAttributes.addFlashAttribute("errorMessage", msg);
			return "redirect:/notice/create";
		}
	}

	@RequestMapping(value = "delete")
	public String delete(@RequestParam("id") String noticeId,
			RedirectAttributes redirectAttributes, HttpServletRequest request) {
		this.noticeService.delete(noticeId);
		redirectAttributes.addAttribute("appId", request.getParameter("appId"));
		redirectAttributes.addFlashAttribute("message", "删除公告成功");
		return "redirect:/notice";
	}

	@Override
	protected String getModuleMenuName() {
		return "云服务";
	}
}
